import random
import pandas as pd
import numpy as np
from datetime import datetime, timedelta


class DataGenerator:
    """模拟数据生成器 - 数据层"""

    @staticmethod
    def generate_users(num=1000):
        """生成用户画像数据"""
        users = []
        age_groups = ["18-25", "26-35", "36-45", "46-55", "56+"]
        for i in range(1, num + 1):
            # 生成用户ID
            users.append({
                "user_id": f"U{i:05d}",
                # 根据年龄组权重随机选择年龄组
                "age_group": random.choices(age_groups,
                                           weights=[0.3, 0.4, 0.15, 0.1, 0.05])[0],
                # 随机选择性别
                "gender": random.choice(["M", "F"]),
                # 根据口味偏好权重随机选择口味偏好
                "preference": random.choices(["sweet", "spicy", "sour", "salty", "mixed"],
                                             weights=[0.3, 0.2, 0.15, 0.25, 0.1])[0],
                # 根据价格敏感度权重随机选择价格敏感度
                "price_sensitivity": random.choices(["low", "medium", "high"],
                                                    weights=[0.2, 0.6, 0.2])[0],
                # 生成最后一次活跃时间
                "last_active": datetime.now() - timedelta(days=random.randint(1, 90))
            })
        return pd.DataFrame(users)


    @staticmethod
    def generate_products(num=500):
        """生成商品数据"""
        categories = {
            "Chips": ["Potato", "Tortilla", "Puffed"],
            "Chocolate": ["Milk", "Dark", "White"],
            "Nuts": ["Almonds", "Cashews", "Walnuts"],
            "Candy": ["Hard", "Gummy", "Chewy"],
            "Dried Fruit": ["Tropical", "Berries", "Traditional"]
        }

        products = []
        for i in range(1, num + 1):
            category = random.choice(list(categories.keys()))
            subcategory = random.choice(categories[category])

            # 口味与品类关联
            flavor_weights = {
                "Chips": {"salty": 0.6, "spicy": 0.3, "sweet": 0.1},
                "Chocolate": {"sweet": 0.8, "mixed": 0.2},
                "Nuts": {"salty": 0.7, "sweet": 0.3},
                "Candy": {"sweet": 0.9, "sour": 0.1},
                "Dried Fruit": {"sweet": 0.7, "sour": 0.3}
            }

            # 获取当前品类的口味和权重
            flavors, weights = zip(*flavor_weights[category].items())
            # 随机选择一个口味
            flavor = random.choices(flavors, weights=weights)[0]

            products.append({
                "product_id": f"P{i:05d}",
                "name": f"{subcategory} {random.choice(['Deluxe', 'Crunchy', 'King', 'Joy', 'Select'])}",
                "category": category,
                "subcategory": subcategory,
                "flavor": flavor,
                "price": round(random.uniform(3, 100), 1),
                "sales": random.randint(100, 10000),
                "stock": random.randint(10, 500),
                "rating": round(random.uniform(3.5, 5.0), 1),
                "is_new": random.choices([True, False], weights=[0.2, 0.8])[0]
            })
        return pd.DataFrame(products)


    @staticmethod
    def generate_interactions(users, products, num=20000):
        """生成用户行为日志"""
        logs = []
        user_ids = users["user_id"].tolist()
        product_ids = products["product_id"].tolist()

        # 创建行为概率矩阵
        action_weights = {
            "view": 0.6,
            "cart": 0.2,
            "buy": 0.15,
            "like": 0.05
        }

        for _ in range(num):
            user = random.choice(user_ids)
            product = random.choice(product_ids)

            # 获取用户和商品特征
            user_profile = users[users["user_id"] == user].iloc[0]
            product_profile = products[products["product_id"] == product].iloc[0]

            # 偏好匹配度影响行为概率
            pref_match = 1.5 if user_profile["preference"] == product_profile["flavor"] else 0.8

            # 价格敏感度影响
            price_factor = 1
            if user_profile["price_sensitivity"] == "high" and product_profile["price"] > 30:
                price_factor = 0.4
            elif user_profile["price_sensitivity"] == "low" and product_profile["price"] < 20:
                price_factor = 1.3

            # 计算最终行为概率
            weighted_actions = {
                action: weight * pref_match * price_factor
                for action, weight in action_weights.items()
            }

            logs.append({
                "log_id": f"L{len(logs) + 1:07d}",
                "user_id": user,
                "product_id": product,
                "action": random.choices(
                    list(weighted_actions.keys()),
                    weights=list(weighted_actions.values())
                )[0],
                "timestamp": datetime.now() - timedelta(minutes=random.randint(1, 43200))
            })
        return pd.DataFrame(logs)